2oneweek.dev

21. This란?

    Tags

  • JavaScript
21. This란? thumbnail

This

  • 하나의 키워드
  • obj.aa() 형태로 호출한 함수(메소드) aa 에서 this로 인스턴스(오브젝트)를 참조할 수 있다.
  • this는 실행 컨텍스트의 This 바인딩 컴포넌트에 바인딩된다. 따라서, 함수 내부에서 this 키워드로 obj를 참조할 수 있다.


this와 Global Object

  • 글로벌 오브젝트에서 this는 글로벌 오브젝트를 참조한다.

    • 글로벌 함수를 호출할 땐, 함수 앞에다가 글로벌 오브젝트를 써주지 않는데, 그건 묵시적으로 글로벌 오브젝트라고 간주하는 것이다.
  • window Object는 JS에서 만든 것이 아니라, 글로벌 오브젝트의 스코프도 아니다. 그러나 window Object와 글로벌 오브젝트를 같은 선상에 두고 사용하곤 한다.

  • 여기에는 Host Object개념이 적용된다.

    function test(){ return this } console.log(this === window) //=> true
    • 전역 함수의 this(Global Object)와 window가 동일


    var value = 100; // 전역변수 console.log(this.value) //=> 100
    • 글로벌 Scope에서 this로 자기 자신을 참조

    • this가 글로벌 오브젝트를 참조하므로, this.value 형태로 글로벌 변수 사용이 가능하다.


    var value = 100; console.log(window.value) //=> 100
    • window가 글로벌 오브젝트를 참조하므로, window.value형태로 글로벌 변수 사용이 가능하다.


    this.value = 100; console.log(window.value) //=> 100
    • 현재 상태에서 this는 Global Object를 참조하므로 value는 Global Object에 설정된다.
    • window가 Global Object를 참조하므로 value를 사용할 수 있다.

    window 오브젝트처럼, 다른 오브젝트를 마치 내것처럼 사용하는 개념을 Host Object라고 한다. "DOM 오브젝트" 또한 Host Object다.

    window와 전역 컨텍스트에서 참조하는 this가 똑같기 때문에, 종종 Global Object가 Window라고 하곤 한다. 그러나 실체는 다르다는 것을 알고 있어야 한다.



this와 window Object

this가 window를 참조하는 경우

window.onload = function(){ console.log(this === window) //=> true }
  • true가 출력된 것은 값과 타입이 같다는 것을 의미한다.
  • this가 window를 참조하게 된 것은, onload()가 비록 이벤트를 처리하는 핸들러 함수라도, function Object다.
  • onload 이벤트가 발생하면, 실행 컨텍스트를 만들게 되고, onload앞에 작성된 window를 this 바인딩 컴포넌트에 바인딩하게 된다.

this로 지역변수 사용하는 경우

window.onload = function(){ var value = 100 console.log(this.value) //=> undefined }
  • 변수 value는 핸들러 함수의 지역변수다.
  • this는 window object를 참조하게 되므로, this.value로 지역변수에 접근할 수 없다.

함수 앞에 작성된 Object를 함수 안에서 this로 참조할 수 있다.



this와 strict 모드

우리는 오브젝트.함수이름()형태로 함수를 호출하지만 글로벌 오브젝트의 경우, 오브젝트의 이름이 없으므로 함수 이름만 작성하여 호출한다.

  • 하지만 strict 모드에서는 window.book()처럼 book()앞에 window를 명시해줘야한다.
  • strict 모드에서 전역함수 호출시에 window를 써주지 않는다면, 실행 컨텍스트의 this 바인딩 컴포넌트에 undefined가 설정되므로, this로 window를 참조할 수 없다.


this가 참조하는 오브젝트

var book = { point : 100, member : { point : 200, get(){ console.log(this === book.member) //true console.log(this.point) //200 } } } book.member.get()
  • get의 실행 컨텍스트 내부의 this바인딩 컴포넌트에는 member를 참조할 수 있도록 설정해놨다.
  • this는 호출한 오브젝트 그 자체를 참조한다.
  • book.member.get()에서 this로 참조하는 것은 member라는 오브젝트다. book은 그저 member를 찾아가는 경로에 불과하다.

this는 함수를 호출할 때 앞의 오브젝트가 뭔지가 중요하다.

var point = 999; var obj = { point: 111, get() { var point = 555; console.log(this === window); console.log(this === obj); console.log(this.point); }, }; var func = obj.get; func(); obj.get();
  • func()에 대한 결과

    true; //console.log(this === window)의 결과 false; //console.log(this === obj)의 결과 999; //console.log(this.point)의 결과
    • func()는 obj의 get과 같은 function Object를 받았다. 그러나 호출할 때 오브젝트를 명시하지 않았다.
    • 따라서 func의 실행 컨텍스트의 this 바인딩 컴포넌트는 Global Object를 참조하게 되며 이때, this는 window다.
    • point도 window에 있는 point를 가져온다.
  • obj.get() 에 대한 결과

    false; //console.log(this === window)의 결과 true; //console.log(this === obj)의 결과 111; //console.log(this.point)의 결과
    • obj.get() 호출할 때 오브젝트는 obj다.
    • 따라서 get()의 실행 컨텍스트의 this 바인딩 컴포넌트는 obj를 참조하게 되며 이때, this는 obj다.
    • point도 obj에 있는 point를 가져온다.


this와 Instance

  • 인스턴스의 목적은, 인스턴스마다 고유의 값을 유지하는데 있다.
  • 인스턴스에서 this의 목적은 this로 인스턴스를 참조하여, 인스턴스의 프로퍼티에 접근하기 위함이다.
    • this를 사용하지 않으면, 메소드에 필요한 값들을 인자로 넘겨주거나, 전역 변수를 사용해야된다. (이 방식은 정적환경의 이점을 버리는 것과 마찬가지다.)
  • __proto__ 접근의 목적
    • new 연산자로 인스턴스를 생성하면, prototype에 연결된 프로퍼티가, 인스턴스의 __proto__에 첨부된다.
    • 따라서, 우리는 this.method()형태로 __proto__에 첨부된(prototype의 메소드) 메소드를 사용할 수 있다.
    • 객체의 prototype에 연결된 메소드는, 인스턴스마다 동일하게 공유할 수 있다. 또한, 인스턴스는 인스턴스대로 고유한 값을 가지고 있을 수도 있다. 값만 다르게하고 일관적인 행동을 보장할 수 있다.

var book = {}; book.Point = function (point) { this.point = point; }; book.Point.prototype.getPoint = function () { console.log(this.point); }; var obj = new book.Point(100); obj.getPoint(); //=> 100 var obj2 = new book.Point(200); obj2.getPoint(); //=> 200 // 아래를 보면, prototype의 프로퍼티를 이용하여 // 동일한 환경을 갖게 할 수 있음을 알 수 있다.(공유) book.Point.prototype.getPoint = function () { console.log("changed"); }; obj.getPoint(); //=> changed obj2.getPoint(); //=> changed book.Point.prototype.test = function () { console.log("asdasd"); };
  • 모든 함수는 생성자 함수가 될 수 있다.
  • book.Point = function (point){}는, book이라는 객체에 Point라는 생성자 함수를 선언한다. 생성자 함수는 첫글자가 대문자라는 관례가 있다. 생성자 함수가 있으므로 new키워드로 book.Point라는 인스턴스를 생성할 수 있다.
  • book.Point는 생성자 함수로, this.point = point코드를 실행하면서, this로 참조하는 오브젝트에 point라는 변수를 선언하고 값을 할당한다.
  • book.Point.prototype.getPointbook.Point의 prototype에 메소드를 추가하는 코드다. 이를 통해 book.Point 인스턴스들은 getPoint라는 함수를 동일하게 갖게 된다.
  • book.Point.prototype.test = function () {} 인스턴스를 생성하고 난 후에, 객체의 Prototype에 메소드를 추가할지라도, 인스턴스마다 추가된 메소드를 들고있다.

인스턴스 목적

  1. 공유
    • 객체의 prototype의 프로퍼티를 인스턴스마다 동일하게 갖게된다. 인스턴스마다 __proto__에 들고있게 된다.
  2. 확장
    • 객체의 prototype만을 확장하여, 인스턴스마다 공유할 수 있다.
  3. 상속
Written by@2-one-week
현재 블로그 개발 중

GitHubLinkedIn